package net.form.processing.classification;


import java.awt.Color;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import net.form.ObjetoClasificador;
import net.form.processing.ObjetoClasificadorKmeans;
import net.model.Clase;
import net.model.RasgoObjeto;
import net.service.ClaseManager;

/**
 * Clase que define la interfaz necesaria para saber si un objeto
 * pertenece a una clase o no.
 * 
 * @author oscar
 * 
 */
public class EvaluadorClase {
	
	private Long id;
	
	@Override
	public int hashCode() {
		return toString().hashCode();
	}

	/**
	 * Clase a evaluar
	 */
	private Clase clase;

	private List<EvaluadorRasgo> rasgos = new ArrayList<EvaluadorRasgo>();

	private ClaseManager claseManager;

	public EvaluadorClase(Clase clase, List<EvaluadorRasgo> rasgos,ClaseManager claseManager) {
		super();
		this.clase = clase;
		this.rasgos = rasgos;
		this.claseManager=claseManager;
	}

	public Color getColor() {
		if (getClase().getColorRgb() != null)
			return new Color(getClase().getColorRgb());
		return null;
	}

	public void setColor(Color color) {
		getClase().setColorRgb(color.getRGB());
	}

	/**
	 * Indica si un objeto pertenece a la clase
	 * 
	 * @param objeto
	 * @return
	 */
	public boolean pertenece(ObjetoClasificador objeto,boolean addRasgoToObject) {
		boolean pertenece = true;
		for (EvaluadorRasgo rasgo : getRasgos()){
			if (rasgo.getRasgoClase().getDeterminante()){
				if (rasgo instanceof EvaluadorHistograma){
						EvaluadorHistograma eh = (EvaluadorHistograma) rasgo;
						eh.setClaseManager(claseManager);
					}
				
				RasgoObjeto rasgoObjeto = rasgo.calcularValor(objeto);
				if (rasgoObjeto != null && addRasgoToObject){
					objeto.addRasgo(rasgoObjeto);
				}
				boolean enRango = rasgo.isEnRango(objeto, rasgoObjeto); 
				if (!enRango)
					pertenece = false;
			}
			else{
				if (addRasgoToObject){
					RasgoObjeto rasgoObjeto = rasgo.calcularValor(objeto);
					if (rasgoObjeto != null){
						objeto.addRasgo(rasgoObjeto);
					}
				}
			}
		}
		return pertenece;
	}
	public boolean pertenece(ObjetoClasificadorKmeans obj) {
		boolean pertenece = true;
		for (EvaluadorRasgo rasgo : getRasgos()){
			if (rasgo.getRasgoClase().getDeterminante()){
				if (rasgo instanceof EvaluadorHistograma){
						EvaluadorHistograma eh = (EvaluadorHistograma) rasgo;
						eh.setClaseManager(claseManager);
					}
				
				RasgoObjeto rasgoObjeto = rasgo.calcularValor(obj.getObject());
				if (rasgoObjeto != null){
					obj.getObject().addRasgo(rasgoObjeto);
				}
				boolean enRango = rasgo.isEnRango(obj, rasgoObjeto); 
				if (!enRango)
					pertenece = false;
			}
			
		}
		return pertenece;
	}

	/**
	 * Indica si un objeto pertenece a la clase
	 * 
	 * @param objeto
	 * @param rasgos Lista con el resultado de la evaluacion de cada rasgo
	 * @return
	 */
	public boolean pertenece(ObjetoClasificador objeto,boolean addRasgoToObject, List<RasgoObjeto> rasgos) {
		boolean pertenece = true;
		for (EvaluadorRasgo rasgo : getRasgos()){
			RasgoObjeto rasgoObjeto = rasgo.calcularValor(objeto);
			if (addRasgoToObject){
//				objeto.addRasgo(rasgoObjeto);
			}
			if (rasgos != null){
				rasgos.add(rasgoObjeto);	
			}
			boolean enRango = rasgo.isEnRango(objeto, rasgoObjeto); 
			if (rasgo.getRasgoClase().getDeterminante()&& !enRango)
				pertenece = false;
		}
		return pertenece;
	}

	public Clase getClase() {
		return clase;
	}

	public void setClase(Clase clase) {
		this.clase = clase;
	}

	public List<EvaluadorRasgo> getRasgos() {
		return rasgos;
	}

	public void setRasgos(List<EvaluadorRasgo> rasgos) {
		if (rasgos != null)
			Collections.sort(rasgos, new EvaluadorRasgoComparator());
		this.rasgos = rasgos;
	}

	 
	public boolean equals(Object o) {
		if (o == null)
			return false;
		if (!(o instanceof EvaluadorClase))
			return false;
		EvaluadorClase c = (EvaluadorClase) o;
		if (getClase() != null)
			return getClase().equals(c.getClase());
		return false;
	}

	 
	public String toString() {
		if (getClase() != null)
			return getClase().getNombre();
		return "";
	}

	public Long getId(){
		return id;
	}
	
	public void setId(Long id){
		this.id = id;
	}



}

